package com.google.jessewilson.codesearch.ui;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.swing.EventListModel;
import com.google.jessewilson.codesearch.api.DefaultQueryResponse;
import com.google.jessewilson.codesearch.api.Line;
import com.google.jessewilson.codesearch.api.Query;
import com.google.jessewilson.codesearch.api.QueryResponse;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author jessewilson
 */
public class ResultsPicker implements EditorComponent<QueryResponse> {

  /** token results object to initiate a new query */
  public static final QueryResponse NEW_QUERY = new DefaultQueryResponse(
      null, new BasicEventList<Line>(), new Query.Builder().searchTerm("New Query...").build(), null);
  private final EventList<QueryResponse> availableResults;
  private JList resultsList;

  private JPanel panel;
  private Action action;

  public ResultsPicker(List<QueryResponse> allResults, final QueryResponse selected) {
    this.availableResults = new BasicEventList<QueryResponse>();
    availableResults.addAll(allResults);
    availableResults.remove(selected);
    availableResults.add(NEW_QUERY);

    this.resultsList = new JList(new EventListModel<QueryResponse>(availableResults));
    this.resultsList.setCellRenderer(new DefaultListCellRenderer() {
      public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        QueryResponse results = (QueryResponse)value;
        return super.getListCellRendererComponent(list, results.getShortDescription(), index, isSelected, hasFocus());
      }
    });

    this.resultsList.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        if(e.getClickCount() == 2 && action != null) {
          action.actionPerformed(new ActionEvent(resultsList, e.getID(), "doubleclick"));
        }
      }
    });

    FormLayout formLayout = new FormLayout(
        "right:min, 3px, left:pref:grow",
        "fill:pref:grow");
    panel = new JPanel(formLayout);

    CellConstraints cc = new CellConstraints();
    panel.add(new JLabel("Queries:"), cc.xy(1, 1, "default, top"));
    panel.add(new JScrollPane(resultsList), cc.xy(3, 1, "fill, fill"));
  }

  public QueryResponse getValue() {
    return (QueryResponse)resultsList.getSelectedValue();
  }

  public void setValue(QueryResponse value) {
    int index = availableResults.indexOf(value);
    if(index == -1) {
      throw new IllegalArgumentException();
    }
    resultsList.setSelectedIndex(index);
  }

  public JComponent getComponent() {
    return panel;
  }

  public static void main(String[] args) {
    final EventList<QueryResponse> results = new BasicEventList<QueryResponse>();
    final ExecutorService executorService = Executors.newFixedThreadPool(1);

    results.add(new DefaultQueryResponse(executorService, new BasicEventList<Line>(), new Query.Builder().searchTerm("ArrayList").build(), null));
    results.add(new DefaultQueryResponse(executorService, new BasicEventList<Line>(), new Query.Builder().searchTerm("HashMap").build(), null));
    results.add(new DefaultQueryResponse(executorService, new BasicEventList<Line>(), new Query.Builder().searchTerm("CollectionList").build(), null));
    results.add(new DefaultQueryResponse(executorService, new BasicEventList<Line>(), new Query.Builder().searchTerm("JTree").build(), null));

    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        JPanel panel = new JPanel(new BorderLayout());
        final ResultsPicker resultsPicker = new ResultsPicker(results, results.get(0));
        resultsPicker.setAction(new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            System.out.println(resultsPicker.getValue());
          }
        });
        panel.add(resultsPicker.getComponent(), BorderLayout.CENTER);
        
        JFrame frame = new JFrame();
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }

  public void setAction(Action action) {
    this.action = action;
  }
}
